RippleButtonBlinker{
	
	classvar <>buttonReturnEntries, looper, pollinterval = 0.1;
	
	var elem;
	
	*initClass{
		buttonReturnEntries = Dictionary.new;	
	}
	
	*start{ // check for expired blinks
		looper =Task.new({
			
			while( 	{true},{ // keep checking until we've reached the set return time, which may have changed
				buttonReturnEntries.keysValuesDo({|button, entry|
				
					if(	button.notClosed,
						{					
							if(
								(entry[0] < SystemClock.seconds) 
								){ // if entry is expired, remove it and reset button
								{
									if( button.notClosed){
										button.states_(entry[1]);
										button.refresh;
									}
								}.defer;
							}							
						},
						{buttonReturnEntries.removeAt(button);}
					);
				
				});
				pollinterval.wait;
			});
		}).start;		
	}
	
	*new{|elem, time, blinkColor, sustain|
		^super.new.blink(elem, time, blinkColor, sustain);
	}
		
	blink{|elemArg, time, blinkColor, sustain = false|

		var newStates;

		elem = elemArg;
	
		if(	blinkColor == nil, 
			{blinkColor = MPGuiConstants.getDefaultBlinkColor;}
		);
		
		
		
		if(
			buttonReturnEntries.at(elem) == nil,
			{buttonReturnEntries.add(elem -> [SystemClock.seconds + time, elem.states.deepCopy])} , //add a new entry
			{buttonReturnEntries.add(elem -> [SystemClock.seconds + time, buttonReturnEntries.at(elem)[1]])} // existing entry -- update time, preserve state entry  
		);
					
		Task.new({
			
				this.setElemColor(blinkColor.blend(Color.black, 0.2)); 
				0.1.wait;				
				this.setElemColor(blinkColor)		
			
		}, AppClock).start;
	}
	
	setElemColor{|color|
		var newStates;
		newStates = Array.fill(elem.states.size, {nil});
		{
			if(elem.notClosed){
				elem.states.do{|state, i|
					newStates[i] = [state[0], state[1], color ]
				};
				elem.states_(newStates);
				elem.refresh;
			}
		}.defer
		
	}
			
}


